import logging
import unittest
from asynctools import UrlFetchTask,AsyncMultiTask,CachedMultiTask
from google.appengine.api.apiproxy_stub_map import UserRPC
from google.appengine.api import apiproxy_rpc
from google.appengine.api.urlfetch_errors import DownloadError,InvalidURLError


import settings



import os


class UrlFetchTaskTests(unittest.TestCase):
    def test_init(self):
        urlFetchTask = UrlFetchTask("url")

    def test_userrpc_instance(self):
        urlFetchTask = UrlFetchTask("url")
        self.assertTrue(isinstance(urlFetchTask.rpc, UserRPC), "should be an instance of UserRPC")

    def test_rpc_idle(self):
        """ over the wire """
        urlFetchTask = UrlFetchTask("http://google.ca")
        self.assertEquals(apiproxy_rpc.RPC.IDLE, urlFetchTask.rpc.state)

    def test_rpc_running(self):
        """ over the wire """
        urlFetchTask = UrlFetchTask("http://google.ca")
        urlFetchTask.make_call()
        self.assertEquals(apiproxy_rpc.RPC.RUNNING, urlFetchTask.rpc.state)

    def test_rpc_finishing(self):
        """ over the wire """
        urlFetchTask = UrlFetchTask("http://google.ca")
        urlFetchTask.make_call()
        urlFetchTask.wait()
        self.assertEquals(apiproxy_rpc.RPC.FINISHING, urlFetchTask.rpc.state)

    def test_cache_key(self):
        URL = "http://google.ca"
        urlFetchTask = UrlFetchTask(URL)
        self.assertEquals(URL, urlFetchTask.cache_key, "should be requested url")

    def test_cache_key_url_cannot_be_None(self):
        """ Fails since the args have not been set """
        self.failUnlessRaises(AssertionError, UrlFetchTask, None)

    def test_cache_result_set_and_get(self):
        """ Fails since the args have not been set """
        URL = "http://google.ca"
        urlFetchTask = UrlFetchTask(URL)
        urlFetchTask.cache_result = "cache val"
        self.assertEquals("cache val", urlFetchTask.cache_result)

    def test_cache_result_not_set_and_get(self):
        """ return None from cache """
        URL = "http://google.ca"
        urlFetchTask = UrlFetchTask(URL)
        self.assertEquals(None, urlFetchTask.cache_result)

class AsyncMultiFetchTest(unittest.TestCase):
    def test_run_multi(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2]
        amt = AsyncMultiTask(tasks)
        amt.run()
        codes = [ f.get_result().status_code for f in amt ]
        self.assertEquals([200, 200], codes)

    def test_run_multi_error(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask("http://")
        urlFetchTask3 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2,urlFetchTask3]
        amt = AsyncMultiTask(tasks)
        amt.run()
        codes = [  ]
        for f in amt:
            try:
                codes.append(f.get_result().status_code)
            except (DownloadError, InvalidURLError), exc:
                codes.append(type(exc))

        self.assertEquals([200, DownloadError,200], codes)

    def test_run_multi_error_appengine(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask("http://")
        urlFetchTask3 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2,urlFetchTask3]
        amt = AsyncMultiTask(tasks)
        amt.run()
        codes = []
        for f in amt:
            try:
                codes.append(f.get_result().status_code)
            except (DownloadError, InvalidURLError), exc:
                codes.append(type(exc))

        self.assertEquals([200L, InvalidURLError,200L], codes)

class CachedMultiFetchTest(unittest.TestCase):
    def test_run_multi(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2]
        amt = CachedMultiTask(tasks)
        amt.run()
        codes = [ f.get_result().status_code for f in amt ]
        self.assertEquals([200, 200], codes)

    def test_run_multi_error(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask("http://")
        urlFetchTask3 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2,urlFetchTask3]
        amt = CachedMultiTask(tasks)
        amt.run()
        codes = [  ]
        for f in amt:
            try:
                codes.append(f.get_result().status_code)
            except (DownloadError, InvalidURLError), exc:
                codes.append(type(exc))

        self.assertEquals([200, DownloadError,200], codes)

    def test_run_multi_error_appengine(self):
        URL = "http://google.ca"
        urlFetchTask1 = UrlFetchTask(URL)
        urlFetchTask2 = UrlFetchTask("http://")
        urlFetchTask3 = UrlFetchTask(URL)

        tasks = [urlFetchTask1,urlFetchTask2,urlFetchTask3]
        amt = CachedMultiTask(tasks)
        amt.run()
        codes = [  ]
        for f in amt:
            try:
                codes.append(f.get_result().status_code)
            except (DownloadError, InvalidURLError), exc:
                codes.append(type(exc))

        self.assertEquals([200, InvalidURLError, 200], codes)
